'use client';

import { type ReactNode, useCallback, useEffect, useState } from 'react';
import { PostEditContext } from '@/contexts/post-edit';
import type { IDifference, IPostEditInfo, IPostNewInfo } from '@/interfaces';
import type { TPostContentType, TPostOtherStates } from '@/types';
import classNames from 'classnames';
import { useSearchParams } from 'next/navigation';
import diff from 'microdiff';

export interface IPostEditConfig {
  isCenter?: boolean;
}

export interface IPostEditForm {
  name: string;
  content: string;
  sectionId: string;
  otherStates: TPostOtherStates[];
  allow: string[];
  block: string[];
  overview: string;
  statement: string;
  cover: string;
  customTags: string[];
  contentType: TPostContentType;
  contentLink?: string;
  images: string[];
  paginationNavLink: {
    prevName?: string;
    prevLink?: string;
    nextName?: string;
    nextLink?: string;
  };
}

export default function Wrapper({
  data,
  children,
}: {
  data: IPostEditInfo | IPostNewInfo;
  children: ReactNode;
}) {
  const isEdit = 'basic' in data;
  const [navItemName, setNavItemName] = useState('编辑');
  const [form, setForm] = useState<IPostEditForm>({
    name: '',
    content: '',
    sectionId: '',
    otherStates: ['DEFAULT'],
    allow: [],
    block: [],
    overview: '',
    statement: '',
    cover: '',
    customTags: [],
    contentType: 'DEFAULT',
    contentLink: '',
    images: [],
    paginationNavLink: {
      prevName: '',
      prevLink: '',
      nextName: '',
      nextLink: '',
    },
  });
  const [config, setConfig] = useState<IPostEditConfig>({
    isCenter: false,
  });
  const urlSearchParams = useSearchParams();
  const [differenceData, setDifferenceData] = useState<IDifference[]>([]);
  const getEditPostForm = useCallback(() => {
    const { section, basic, details, content } = data as IPostEditInfo;
    return {
      cover: basic.cover || '',
      customTags: basic.customTags,
      name: basic.name,
      otherStates:
        details.otherStates.length === 0 ? ['DEFAULT'] : details.otherStates,
      overview: basic.overview || '',
      contentType: basic.contentType,
      contentLink: basic.contentLink || '',
      sectionId: section.id + '',
      statement: basic.statement || '',
      allow: (details.allow || []).map((item) => item + ''),
      block: (details.block || []).map((item) => item + ''),
      paginationNavLink: basic.paginationNavLink
        ? {
            prevName: basic.paginationNavLink.prevName || '',
            prevLink: basic.paginationNavLink.prevLink || '',
            nextName: basic.paginationNavLink.nextName || '',
            nextLink: basic.paginationNavLink.nextLink || '',
          }
        : {
            prevName: '',
            prevLink: '',
            nextName: '',
            nextLink: '',
          },
      content,
    } as IPostEditForm;
  }, [data]);
  const getNewPostForm = useCallback(() => {
    const { sections } = data;
    return {
      sectionId:
        urlSearchParams.get('sectionId') ||
        urlSearchParams.get('sid') ||
        (sections.length > 0 ? sections[0].id + '' : ''),
    } as IPostEditForm;
  }, [data, urlSearchParams]);

  useEffect(() => {
    let newForm: IPostEditForm;
    if (isEdit) {
      newForm = getEditPostForm();
    } else {
      newForm = getNewPostForm();
    }

    setForm({ ...form, ...newForm });
  }, []);
  useEffect(() => {
    let obj: {};
    if (isEdit) {
      obj = getEditPostForm();
    } else {
      obj = {};
    }

    setDifferenceData(diff(obj, form));
  }, [form, getEditPostForm, getNewPostForm, isEdit]);

  function onNavItemName(value: string) {
    setNavItemName(value);
  }

  function onForm(data: Partial<IPostEditForm>) {
    setForm({ ...form, ...data });
  }

  function onConfig(data: Partial<IPostEditConfig>) {
    setConfig({ ...config, ...data });
  }

  return (
    <PostEditContext.Provider
      value={{
        navItemName,
        form,
        setForm,
        config,
        onConfig,
        onNavItemName,
        onForm,
        differenceData,
      }}
    >
      <div className="col py-4">
        <div
          className={classNames({
            container: config.isCenter,
          })}
        >
          {children}
        </div>
      </div>
    </PostEditContext.Provider>
  );
}
